package kioscodeal

import grails.transaction.Transactional

@Transactional
class PedidoService {
	
	def geocodingService
	
	private static final double FACTOR = 0.06 * 1.1515 * 1.609344 * 1000 * 1000

	def geolocalize(Pedido pedidoInstance){
		def coordenada = new Coordenada()
		coordenada.save()
		pedidoInstance.coord = coordenada
		
		def latlng = geocodingService.findLatLngByAddress("${pedidoInstance?.cliente?.calle} ${pedidoInstance?.cliente?.numeroDireccion}, ${pedidoInstance?.cliente?.localidad}")
		if(latlng){
			pedidoInstance.coord.lat = latlng.lat
			pedidoInstance.coord.lng = latlng.lng
		}
		
		def comercioInstance = Comercio.findById(1)
		pedidoInstance.origen = comercioInstance.coord
		def coord1 = comercioInstance.coord
		def coord2 = pedidoInstance.coord
		
		pedidoInstance.distanciaComercioCliente = Math.toDegrees(Math.acos(Math.sin(Math.toRadians(coord1['lat'])) * Math.sin(Math.toRadians(coord2['lat'])) +
		Math.cos(Math.toRadians(coord1['lat'])) * Math.cos(Math.toRadians(coord2['lat'])) *
		Math.cos(Math.toRadians(coord1['lng'] - coord2['lng'])))) * FACTOR
		
		if (!pedidoInstance.save(flush: true)) {           
            return false
		} else {
			return true
		}				
	}
	
	def obtenerDescuentoAplicar(Double importeCompra){
		def descuentoAplicar = null
		def descuentos = Descuento.findAll()
		descuentos.each { Descuento unDescuento ->
			if (unDescuento.importeAplicado <= importeCompra){
				def fechaActual = new Date()
				if (unDescuento.fechaDesde.getTime() <= fechaActual.getTime() && unDescuento.fechaHasta.getTime() >= fechaActual.getTime()){
					if (descuentoAplicar != null && descuentoAplicar.porcentaje < unDescuento.porcentaje){
						descuentoAplicar = unDescuento
					} else {
						descuentoAplicar = unDescuento
					}
				}
			}
		}
		
		return descuentoAplicar
	}
	
	def cargarProducto(Long idProducto, Integer cantidadCarrito, def productoPedidoInstanceList, def listadoCompra, 
		def datosImporteCompra, def sessionLocal) {
		if (sessionLocal.carrito == null){
			if (cantidadCarrito > 0){
				sessionLocal.carrito = [
					[producto: idProducto, cantidad: cantidadCarrito]
				]
			}
		} else {
			boolean encontrado = false
			sessionLocal.carrito.each{
				if (it.'producto' == idProducto){
					it.'cantidad' = cantidadCarrito
					encontrado = true
				}
			}
			if (!encontrado && cantidadCarrito > 0){
				sessionLocal.carrito += [
					[producto: idProducto, cantidad: cantidadCarrito]
				]
			} else if (encontrado && cantidadCarrito <= 0){
				buscarYeliminarElementoCarrito(idProducto)
			}
		}
	
		for (def producto in Producto.findAll()){
			ProductoPedido productoPedido = new ProductoPedido()
			productoPedido.producto = producto
			productoPedido.cantidad = 0;
			sessionLocal.carrito.each{
				if (it.'producto' == producto.id){
					productoPedido.cantidad = it.'cantidad'
				}
			}
			productoPedido.importeTotal = producto.precioUnitario * productoPedido.cantidad
			productoPedidoInstanceList.add(productoPedido)
		}
		
		def importeCompra = 0.00
		for (def pp in productoPedidoInstanceList){
			if (pp.cantidad > 0){
				listadoCompra.add(pp)
				importeCompra += pp.importeTotal
			}
		}
		
		//Descuento
		def descuentoAplicar = obtenerDescuentoAplicar(importeCompra)
		def porcentajeDescuento = 0.00
		//Aplico descuento
		if (descuentoAplicar != null){
			importeCompra -= (importeCompra * (descuentoAplicar.porcentaje / 100))
			porcentajeDescuento = new Double(descuentoAplicar.porcentaje)
		}
		
		datosImporteCompra.importeTotal = importeCompra
		datosImporteCompra.porcentajeDescuento = porcentajeDescuento		
	}
	
	def buscarYeliminarElementoCarrito(Long idProducto, def sessionLocal){
		if (sessionLocal.carrito != null){
			def cantidadProducto = 0
			def encontrado = true
			sessionLocal.carrito.each{
				if (it.'producto' == idProducto){
					encontrado = true
					cantidadProducto = it.'cantidad'
				}
			}
			
			if (encontrado){
				sessionLocal.carrito.remove([producto: idProducto, cantidad: cantidadProducto])
			}
		}
	}
	
	def saveCarrito(def sessionLocal, def datosImporteCompra) {
		def listadoPedido = null
		if (sessionLocal.carrito != null){	
			def importeCompra = 0.00 		
			sessionLocal.carrito.each{
				if (it.'cantidad' > 0){
					def productoCarrito = Producto.findById(it.'producto')
					if (productoCarrito != null){
						def productoPedido = new ProductoPedido(
								producto: productoCarrito,
								cantidad: it.'cantidad',
								estadoProductoPedido: EstadoProductoPedido.NO_ENVIADO
							).save(failOnError:true)
						
						if (listadoPedido == null && productoPedido != null){
							listadoPedido = [productoPedido]
							importeCompra += (productoPedido.cantidad * productoPedido.producto.precioUnitario)
						} else if (listadoPedido != null && productoPedido != null){
							listadoPedido += [productoPedido]
							importeCompra += (productoPedido.cantidad * productoPedido.producto.precioUnitario)
						}
					}
				}
			}
			datosImporteCompra.importeTotal = importeCompra
			def comercioInstance = Comercio.findById(1)
						
			def importeOk = (sessionLocal?.user.minimoCompra == null || sessionLocal?.user.minimoCompra == 0) ? comercioInstance.minimoCompraGeneral : sessionLocal?.user.minimoCompra
			if (importeCompra >= importeOk){
				return listadoPedido
			} else {
				sessionLocal.noSuperaImporteMinimo = true
				
				def importeFaltante = 0.00
				if (sessionLocal?.user.minimoCompra != null && importeCompra < sessionLocal?.user.minimoCompra){
					importeFaltante = sessionLocal?.user.minimoCompra - importeCompra
				} else {
					importeFaltante = comercioInstance.minimoCompraGeneral - importeCompra
				}
				
				sessionLocal.importeMinimoFaltante = importeFaltante
				return null
			}
		}
		
		return null
	}
	
	def procesarCarrito(def listadoPedido, def datosImporteCompra, def sessionLocal){		
		def importeCompra = datosImporteCompra.importeTotal
		def pedidoInstance = null
		if (listadoPedido != null){
			//Limpio los datos en sesion
			sessionLocal.carrito = null
			
			//Descuento
			def descuentoAplicar = obtenerDescuentoAplicar(importeCompra)
			//Aplico descuento
			if (descuentoAplicar != null){
				importeCompra -= (importeCompra * (descuentoAplicar.porcentaje / 100))
			}
			def fechaActual = GregorianCalendar.getInstance()
			pedidoInstance = new Pedido(
				cliente: sessionLocal?.user,
				estadoPedido: EstadoPedido.PENDIENTE,
				calificacionPedido: CalificacionPedido.SIN_CALIFICACION,
				fechaCreacion: fechaActual.getTime(),
				productoPedidos: listadoPedido,
				descuento: descuentoAplicar,
				importeTotal: importeCompra
			)			
		}
		
		return pedidoInstance
	}
}
